package cn.chencq.springcloud.zuul.filter;

import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;

/**
 * 
 * @ClassName: RequestLogFilter
 * @Description: zuul filter
 * @author: chaoqun.chen
 * @date: 2019年5月12日 下午3:12:46
 */
@Component
public class RequestLogFilter extends ZuulFilter {

	private static final Logger logger = LoggerFactory.getLogger(RequestLogFilter.class);

	@Override
	public boolean shouldFilter() {
		return true;
	}

	@Override
	public String filterType() {

		return FilterConstants.PRE_TYPE;
	}

	@Override
	public int filterOrder() {

		return -1;
	}

	private String get32UUID() {
		return UUID.randomUUID().toString().replace("-", "").toLowerCase();
	}

	@Override
	public Object run() throws ZuulException {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest httpServletRequest = ctx.getRequest();
		String requestUri = httpServletRequest.getRequestURI();
		StringBuffer requestUrl = httpServletRequest.getRequestURL();
		String method = httpServletRequest.getMethod();

		String rid = get32UUID();
		ctx.addZuulRequestHeader("rid", rid);
		MDC.put("rid", rid);

		String ip = getIpAddress(httpServletRequest);
		ctx.addZuulRequestHeader("ip", ip);
		MDC.put("ip", ip);
		
		// 记录报文日志
		try {
			InputStream in = httpServletRequest.getInputStream();
			String requestBody = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
			logger.info("请求URL:{}, 请求URI:{}, Method:{}", requestUrl, requestUri, method);
			// 请求url参数
			Map<String, String[]> map = httpServletRequest.getParameterMap();
			// 打印请求
			if (map != null) {
				logger.info("请求参数params:{}", JSONObject.toJSONString(map));
			}
			// 打印存在Body的日志
			if (!StringUtils.isEmpty(requestBody)) {
				logger.info("请求Body:{}", requestBody);
			}
		} catch (Exception e) {
			logger.error("请求日志报文记录异常, URL:{}, uri:{}, method:{}", requestUrl, requestUri, method, e);
		}
		return null;
	}

	public static String getIpAddress(HttpServletRequest request) {
		String ip = null;
		try {
			ip = request.getHeader("x-forwarded-for");
			if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("Proxy-Client-IP");
			}
			if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("WL-Proxy-Client-IP");
			}
			if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("HTTP_CLIENT_IP");
			}
			if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getHeader("HTTP_X_FORWARDED_FOR");
			}
			if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
				ip = request.getRemoteAddr();
			}
		} catch (Exception e) {
			logger.error("获取IP ERROR ", e);
		}
		return ip;
	}
}
